/*
 * @Date: 2025-05-11 14:27:12
 * @LastEditors: 不吃芒果 syuyi_1994@163.com
 * @LastEditTime: 2025-05-22 23:03:38
 */

/**
 * HTTP请求工具类
 */
import config from '../../config/config.js';

// API配置
const apiConfig = config.api;
const apiUrls = config.apiUrls;

// 请求拦截器
const requestInterceptor = (options) => {
  // 获取token
  const token = uni.getStorageSync('token');
  
  // 添加token到请求头
  if (token) {
    options.header = {
      ...options.header,
      'Authorization': `Bearer ${token}`
    };
  }
  
  // 添加默认配置
  options.url = apiConfig.baseURL + options.url;
  options.timeout = options.timeout || apiConfig.timeout;
  options.header = {
    ...apiConfig.headers,
    ...options.header
  };
  
  return options;
};

// 响应拦截器
const responseInterceptor = (response) => {
  // 统一处理响应
  const { data, statusCode } = response;
  // 检查HTTP状态码
  if (statusCode >= 200 && statusCode < 300) {
    // 检查API返回的业务状态码
    if (data && data.code !== undefined) {
      // API返回了业务状态码
      if (data.code === 200 || data.code === 0 || data.code === '200' || data.code === '0') {
        // 业务处理成功
        return data.data !== undefined ? data.data : data;
      } else if (data.code === 401 || data.code === '401') {
        // 业务状态码表示未登录
        uni.removeStorageSync('token');
        uni.removeStorageSync('userInfo');
        uni.removeStorageSync('us_oid');
        uni.showToast({
          title: data.msg || '登录已过期，请重新登录',
          icon: 'none',
          duration: 2000
        });
        setTimeout(() => {
          uni.navigateTo({ url: '/pages/index/index' });
        }, 2000);
        return Promise.reject(new Error(data.msg || '身份验证失败'));
      } else {
        // 其他业务错误
        const errorMsg = data.msg || `请求失败，错误码：${data.code}`;
        uni.showToast({
          title: errorMsg,
          icon: 'none',
          duration: 2000
        });
        return Promise.reject(new Error(errorMsg));
      }
    } else {
      // 没有业务状态码，直接返回数据
      return data;
    }
  } else {
    // 其他HTTP错误
    const errorMsg = (data && data.msg) || `请求失败，状态码：${statusCode}`;
    uni.showToast({
      title: errorMsg,
      icon: 'none',
      duration: 2000
    });
    return Promise.reject(new Error(errorMsg));
  }
};

/**
 * 封装uni.request方法
 * @param {Object} options - 请求选项
 * @returns {Promise} - 返回Promise对象
 */
const request = (options) => {
  // 应用请求拦截器
  options = requestInterceptor(options);
  
  return new Promise((resolve, reject) => {
    uni.request({
      ...options,
      success: (res) => {
        try {
          const result = responseInterceptor(res);
          resolve(result);
        } catch (error) {
          reject(error);
        }
      },
      fail: (err) => {
        uni.showToast({
          title: '网络错误，请检查网络连接',
          icon: 'none',
          duration: 2000
        });
        reject(new Error('网络请求失败'));
      }
    });
  });
};

/**
 * GET请求
 * @param {String} url - 请求地址
 * @param {Object} params - 请求参数
 * @param {Object} header - 请求头
 * @returns {Promise} - 返回Promise对象
 */
const get = (url, params = {}, header = {}) => {
  return request({
    url,
    method: 'GET',
    data: params,
    header
  });
};

/**
 * POST请求
 * @param {String} url - 请求地址
 * @param {Object} data - 请求参数
 * @param {Object} header - 请求头
 * @returns {Promise} - 返回Promise对象
 */
const post = (url, data = {}, header = {}) => {
  return request({
    url,
    method: 'POST',
    data,
    header
  });
};

/**
 * PUT请求
 * @param {String} url - 请求地址
 * @param {Object} data - 请求参数
 * @param {Object} header - 请求头
 * @returns {Promise} - 返回Promise对象
 */
const put = (url, data = {}, header = {}) => {
  return request({
    url,
    method: 'PUT',
    data,
    header
  });
};

/**
 * DELETE请求
 * @param {String} url - 请求地址
 * @param {Object} data - 请求参数
 * @param {Object} header - 请求头
 * @returns {Promise} - 返回Promise对象
 */
const del = (url, data = {}, header = {}) => {
  return request({
    url,
    method: 'DELETE',
    data,
    header
  });
};

/**
 * 上传文件
 * @param {String} url - 上传地址
 * @param {String} filePath - 文件路径
 * @param {String} name - 文件对应的key
 * @param {Object} formData - 附加表单数据
 * @param {Object} header - 请求头
 * @returns {Promise} - 返回Promise对象
 */
const upload = (url, filePath, name = 'file', formData = {}, header = {}) => {
  const token = uni.getStorageSync('token');
  
  if (token) {
    header = {
      ...header,
      'Authorization': `Bearer ${token}`
    };
  }
  
  return new Promise((resolve, reject) => {
    uni.uploadFile({
      url: apiConfig.baseURL + url,
      filePath,
      name,
      formData,
      header: {
        ...apiConfig.headers,
        ...header
      },
      success: (res) => {
        if (res.statusCode >= 200 && res.statusCode < 300) {
          // 将返回的JSON字符串转换为对象
          let data;
          try {
            data = JSON.parse(res.data);
          } catch (e) {
            data = res.data;
          }
          resolve(data);
        } else {
          reject(new Error(`上传失败，状态码：${res.statusCode}`));
        }
      },
      fail: () => {
        uni.showToast({
          title: '上传失败，请检查网络连接',
          icon: 'none',
          duration: 2000
        });
        reject(new Error('上传失败'));
      }
    });
  });
};

// API服务
const api = {};

// 自动生成API方法
Object.keys(apiUrls).forEach(key => {
  api[key] = (data, header) => {
    // 默认使用POST方法，可根据实际需要修改
    if (data.method === 'GET') {
      delete data.method;
      return get(apiUrls[key], data, header);
    } else if (data.method === 'PUT') {
      delete data.method;
      return put(apiUrls[key], data, header);
    } else if (data.method === 'DELETE') {
      delete data.method;
      return del(apiUrls[key], data, header);
    } else if (data.method === 'POST') {
      delete data.method;
      return post(apiUrls[key], data, header);
    } else if (data.method === 'UPLOAD') {
      delete data.method;
      return upload(apiUrls[key], data, header);
    }
  };
});

export default {
  request,
  get,
  post,
  put,
  delete: del,
  upload,
  api
};
